#include <iostream>
#include <string>
using namespace std;

/*
给你两个字符串 s 和 goal ，只要我们可以通过交换 s 中的两个字母得到与 goal 相等的结果，就返回 true ；否则返回 false 。

交换字母的定义是：取两个下标 i 和 j （下标从 0 开始）且满足 i != j ，接着交换 s[i] 和 s[j] 处的字符。

例如，在 "abcd" 中交换下标 0 和下标 2 的元素可以生成 "cbad" 。
 

示例 1：

输入：s = "ab", goal = "ba"
输出：true
解释：你可以交换 s[0] = 'a' 和 s[1] = 'b' 生成 "ba"，此时 s 和 goal 相等。
示例 2：

输入：s = "ab", goal = "ab"
输出：false
解释：你只能交换 s[0] = 'a' 和 s[1] = 'b' 生成 "ba"，此时 s 和 goal 不相等。
示例 3：

输入：s = "aa", goal = "aa"
输出：true
解释：你可以交换 s[0] = 'a' 和 s[1] = 'a' 生成 "aa"，此时 s 和 goal 相等。
示例 4：

输入：s = "aaaaaaabc", goal = "aaaaaaacb"
输出：true

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/buddy-strings
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
*/



class Solution {
public:
    bool buddyStrings(string s, string goal) {
        if(s.size() != goal.size()) return false;   //长度不相等，则直接false
        int flag = 0;   //记录交换次数，只能交换一次
        for(int i = 0; i < s.size(); ++i){
            if(s[i] == goal[i]) continue;
            else{
                int index = i;  //记录s和goal不相等时刻的下标
                for(int j = index + 1; j < s.size(); ++j){
                    /*
                    goal不相等位置(index)的字符在s的后续字符(j)中找到
                    同时在该位置(j)中的goal的字符也是s(index)不相等位置的字符
                    */
                    if(s[j] == goal[index] && s[index] == goal[j]){
                        swap(s[index], s[j]);
                        flag++;
                        break;
                    }
                    else if(j == s.size() - 1)  //没能找到相同的字符且遍历完后续子串，则false
                        return false;
                }
            }
            if(flag == 1) break;    //只交换一次，因此交换后外层跳出循环
        }
        if(s == goal){
            if(flag == 1) return true;  //字符串相等并交换了一次，回true
            else if(flag == 0){//字符串相等，没有进行交换，但若在同一字符串中有相等字符，也是true，例:aa
                for(int i = 0; i < s.size(); ++i)
                    for(int j = i+1; j < s.size(); ++j)
                        if(s[i] == s[j]) return true;
                return false;
            }
        }
        return false;
    }
};